有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

用于在文本字段中键入的java Javascript执行与sendKeys不同

我在Linux机器上运行我的测试,并且有以下代码,它不能正确地键入文本-

visibleElement.clear();
visibleElement.sendKeys("I am running on linux machine");

在UI中,实际上输入了不同的文本,比如“在linux机器上运行”、“在linux机器上运行”等等

因此,为了处理这个问题,我像-

JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("arguments[0].value='I am running on linux machine';", visibleElement);

这会按文本字段中的方式键入文本,但键入后,会出现Save按钮,该按钮预计将启用,但未启用

但如果使用sendKeys,则该按钮将启用

你能告诉我为什么这个javascript行为不同,并提供正确的javascript吗

在一个解决方案中,这两种方法是如何工作的(不点击tab来启用按钮,因为在我的情况下这不是正确的方法)


共 (3) 个答案

  1. # 1 楼答案

    设置arguments[0].value = "..."设置文本字段上的值,但该元素上不会触发任何事件。“保存”按钮可能正在等待change事件发生在<form>内的某个地方。您需要使用JavaScript在文本框上手动触发更改事件。见How can I trigger an onchange event manually?

    你描述的行为让我觉得JavaScript已经在监听更改事件,然后扰乱单词的顺序,就好像尤达已经键入了它们一样。(或者输入尤达的名字?)手动触发更改事件可能会启用“保存”按钮,并且最终可能会得到与使用sendKeys相同的文本。如果是这种情况,您可能还希望使用JavaScript启用“保存”按钮:

    // Set the input text
    jse.executeScript("arguments[0].value='I am running on linux machine';", visibleElement);
    
    // Find the "Save" button
    WebElement saveButton = driver.findElement(...);
    
    // Enable the save button
    jse.executeScript("arguments[0].disabled = false;", saveButton);
    
    saveButton.click();
    
  2. # 2 楼答案

    从元素可见开始,并不能保证元素是可交互的,也就是说,你可以直接调用^{

    要在所需元素中调用sendKeys(),需要为elementToBeClickable()引入WebDriverWait,并且可以使用以下Locator Strategy

    WebElement clickableElement = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(visibleElement))
    clickableElement.click();
    clickableElement.clear();
    clickableElement.sendKeys("I am running on linux machine");
    

    You can find a relevant detailed discussion in How to preserve the character sequence sent through SendKeys() method through Selenium and C#


    tl;博士

    Selenium: How selenium identifies elements visible or not? Is is possible that it is loaded in DOM but not rendered on UI?

  3. # 3 楼答案

    尝试用承诺式或异步/等待式写作

    async clear_elem(elem) {
        // elem.clear(), MAY not work always because of some background JS
        await elem.sendKeys(protractor.Key.chord(protractor.Key.CONTROL, 'a'));
        await elem.sendKeys(protractor.Key.DELETE);
        // Can await here for Application Load
    }
    
    reverse_string = as => as.split('').reverse().join();
    // intersperse - Places an Item in between elements of an array
    // ex: intersperse('k')("abc") => ['a', 'k', 'b', 'k', 'c']
    intersperse = x => as => as.split('').reduce((acc, x) => [...acc, a, x], []).slice(0, -1);
    
    (async () => {
        // Assuming you have element - visibleElement
        await browser.wait(protractor.ExpectedConditions.elementToBeClickable(visibleElement), default_timeout);
    
        await clear_elem(visibleElement);
        const str = reverse_string('I  am running on linux machine');
        const sequence_of_characters = intersperse(protractor.Key.HOME)(str);
        // e, HOME, n, HOME, i, HOME, h, HOME, ...
        await visibleElement.sendKeys(protractor.Key.chord(...sequence_of_characters));
    })();